import type { SimpleModeConfig } from 'rc-tree-select/lib/interface';
import { TreeDataItem } from '@/biz-components/hooks/interface';
import { ReactNode, useEffect, useState } from 'react';

function parseSimpleTreeData(
  treeData: TreeDataItem[],
  { id, pId, rootPId }: SimpleModeConfig,
): TreeDataItem[] {
  const keyNodes = {};
  const rootNodeList: TreeDataItem[] = [];

  // Fill in the map
  const nodeList = treeData.map((node) => {
    const clone = { ...node };
    const key = id ? clone[id] : '';
    keyNodes[key] = clone;
    clone.key = clone.key || key;
    return clone;
  });

  // Connect tree
  nodeList.forEach((node) => {
    const parentKey = pId ? node[pId] : '';
    const parent = keyNodes[parentKey];

    // Fill parent
    if (parent) {
      parent.children = parent.children || [];
      parent.children.push(node);
    }

    // Fill root tree node
    if (parentKey === rootPId || (!parent && rootPId === '')) {
      rootNodeList.push(node);
    }
  });

  return rootNodeList;
}

const formatTreeData = (
  treeData: TreeDataItem[],
  getLabelProp: (node: TreeDataItem) => ReactNode,
): TreeDataItem[] => {
  function dig(dataNodes: TreeDataItem[]) {
    return (dataNodes || []).map((node) => {
      const { key, value, children, ...rest } = node;

      const mergedValue = 'value' in node ? value : key;

      const dataNode: TreeDataItem = {
        ...rest,
        key: mergedValue,
        value: mergedValue,
        title: getLabelProp(node),
      };

      if (children) {
        dataNode.children = dig(children);
      }

      return dataNode;
    });
  }

  return dig(treeData);
};

export default function useTreeData(
  treeData: TreeDataItem[],
  {
    getLabelProp,
    keyword,
  }: {
    getLabelProp: (node: TreeDataItem) => ReactNode;
    keyword: string | undefined;
  },
): TreeDataItem[] {
  const [newTreeData, setNewTreeData] = useState<TreeDataItem[]>([]);

  useEffect(() => {
    setNewTreeData(
      formatTreeData(
        parseSimpleTreeData(treeData, {
          id: 'id',
          pId: 'pId',
          rootPId: '',
        }),
        getLabelProp,
      ),
    );
  }, [treeData, keyword]);

  return newTreeData;
}
